package com.naiterui.ehp.bs.patient.service.security.impl;

import java.io.IOException;

import javax.servlet.http.HttpServletResponse;

import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.naiterui.common.redis.RedisUtil;
import com.naiterui.ehp.bp.domain.Patient;
import com.naiterui.ehp.bp.support.exception.PublicService;
import com.naiterui.ehp.bp.support.utils.JsonMapper;
import com.naiterui.ehp.bs.patient.dao.IPatientDao;
import com.naiterui.ehp.bs.patient.exception.ExceptionCodes;
import com.naiterui.ehp.bs.patient.service.security.ISecurityService;
import com.naiterui.ehp.bs.patient.utils.cache.PatientCacheUtil;

@Service
public class ApSecurityServiceImpl implements ISecurityService {

    private static final Logger LOGGER = LoggerFactory.getLogger(ApSecurityServiceImpl.class);

    @Autowired
    IPatientDao patientDao;

    @Override
    public boolean saveCheckToken(Long patientId, String token) throws IOException {

        return this.saveCheckToken(patientId.toString(), token, null);
    }

    /*
     * 校验token-response写入异常信息
     * ISecurityService.saveCheckToken()
     */
    @Override
    public boolean saveCheckToken(String patientId, String token, HttpServletResponse response) throws IOException {

        if (!StringUtils.isNumeric(patientId) || StringUtils.isBlank(token)) {
            this.stuffErrorCode(response, ExceptionCodes.TOLOGIN);
            return false;
        }

        // 验证患者的账户状态--是否禁用
        String accountKey = PatientCacheUtil.PATIENT_ACCOUNT_KEY + patientId;
        Object cacheStauts = RedisUtil.valueOps().getObject(accountKey);
        // 医生已经被禁用
        if (cacheStauts != null) {
            if ("1".equals(String.valueOf(cacheStauts))) {
                // 获取患者账号状态
                this.stuffErrorCode(response, ExceptionCodes.PATIENT_ACCOUNT_ERROR);
                return false;
            }
        }

        // 验证患者token
        try {
            String cacheKey = PatientCacheUtil.PATIENT_LOGIN_TOKEN_KEY + patientId;
            String cacheToken = RedisUtil.valueOps().getString(cacheKey);
            if (token.equals(cacheToken)) {
                return true;
            }

        } catch (Exception e) {
            LOGGER.error("从redis中获取缓存用户登陆token失败,patientId=" + patientId, e);
        }

        Patient p = this.patientDao.get(Long.parseLong(patientId));

        if (p == null) {
            // 提示去登陆
            this.stuffErrorCode(response, ExceptionCodes.TOLOGIN);
            return false;
        }

        if (p.getAccountStatus() == 1) {
            // 提示用户已经被禁用
            this.stuffErrorCode(response, ExceptionCodes.PATIENT_ACCOUNT_ERROR);
            return false;
        }

        String dbToken = p.getToken();
        if (!token.equals(dbToken)) {
            // 提示去登陆
            this.stuffErrorCode(response, ExceptionCodes.TOLOGIN);
            return false;
        }

        return true;
    }

    /**
     * SecurityServiceImpl.stuffErrorCode()
     *
     * @param response
     * @param errorCode
     *
     * @throws IOException
     * @Author mudou
     * @Date 2017年7月10日
     * @since 2.8.0
     */
    private void stuffErrorCode(HttpServletResponse response, int errorCode) throws IOException {
        if (null == response) {
            return;
        }
        response.getWriter().println(JsonMapper.toJson(PublicService.returnResponseVO(errorCode)));
    }

}
